package cn.xd.base.application.aop;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONUtil;
import cn.xd.base.domain.entity.BuriedPoint;
import cn.xd.base.domain.repository.BuriedPointRepository;
import cn.xd.common.domain.auth.CurrentUser;
import cn.xd.web.utils.SecurityUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 记录日志
 */
@Order(Ordered.LOWEST_PRECEDENCE - 1) // 确保比 @Transaction 优先（after切点晚于事务）
@Component
@Slf4j
@Aspect
public class SyncBuriedPointAspect {
    @Resource
    private BuriedPointRepository buriedPointRepository;

    @Pointcut("@annotation(syncBuriedPoint)")
    private void BuriedPointPointCut(SyncBuriedPoint syncBuriedPoint) {
    }


    @AfterReturning(pointcut = "BuriedPointPointCut(syncBuriedPoint)", returning = "returning", argNames = "point,syncBuriedPoint,returning")
    public void syncBuriedPoint(JoinPoint point, SyncBuriedPoint syncBuriedPoint, Object returning) throws Throwable {
        String name = point.getSignature().getName();
        String declaringTypeName = point.getSignature().getDeclaringTypeName();
        int modifiers = point.getSignature().getModifiers();
        String kind = point.getKind();
        log.error("name:" + name);
        log.error("declaringTypeName:" + declaringTypeName);
        log.error("modifiers:" + modifiers);
        log.error("kind:" + kind);
        for (Object arg : point.getArgs()) {
            log.error(arg.toString());
        }
        CurrentUser currentUser = SecurityUtils.getUserNotThrow();
        Long userId = null;
        Integer userType = null;
        if (ObjUtil.isNotEmpty(currentUser)) {
            userId = currentUser.getId();
            userType = currentUser.getAppUserType().getCode();
        }
        buriedPointRepository.save(BuriedPoint.success(declaringTypeName + "@" + name, JSONUtil.toJsonStr(point.getArgs()), syncBuriedPoint.remark(), userId, userType, returning));

    }

    @AfterThrowing(pointcut = "BuriedPointPointCut(syncBuriedPoint)", throwing = "throwable", argNames = "point,syncBuriedPoint,throwable")
    public void syncBuriedPoint(JoinPoint point, SyncBuriedPoint syncBuriedPoint, Throwable throwable) throws Throwable {
        String name = point.getSignature().getName();
        String declaringTypeName = point.getSignature().getDeclaringTypeName();
        int modifiers = point.getSignature().getModifiers();
        String kind = point.getKind();
        CurrentUser currentUser = SecurityUtils.getUserNotThrow();
        Long userId = null;
        Integer userType = null;
        if (ObjUtil.isNotEmpty(currentUser)) {
            userId = currentUser.getId();
            userType = currentUser.getAppUserType().getCode();
        }
        buriedPointRepository.save(BuriedPoint.error(declaringTypeName + "@" + name, JSONUtil.toJsonStr(point.getArgs()), syncBuriedPoint.remark(), userId, userType, throwable));

    }
}
